<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" >

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js" integrity="sha256-iM4Yzi/zLj/IshPWMC1IluRxTtRjMqjPGd97TZ9yYpU=" crossorigin="anonymous"></script>
  <link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Cousine|Inconsolata" rel="stylesheet">
  <link rel="shortcut icon" type="image/png" href="/favicon.png">

  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/css/css/fontawesome-all.min.css">
  <link rel="stylesheet" href="/css/css/work-sans-v7.css">
  <script src="/js/main.js"></script>

  <!-- Begin Jekyll SEO tag v2.6.1 -->
<title>Setting Up a Testnet | Hive Developer</title>
<meta name="generator" content="Jekyll v4.0.0" />
<meta property="og:title" content="Setting Up a Testnet" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="“Quick-start” for deploying a Hive-based Testnet." />
<meta property="og:description" content="“Quick-start” for deploying a Hive-based Testnet." />
<link rel="canonical" href="setting-up-a-testnet.html" />
<meta property="og:url" content="setting-up-a-testnet.html" />
<meta property="og:site_name" content="Hive Developer" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2020-08-26T11:52:22-07:00" />
<script type="application/ld+json">
{"description":"“Quick-start” for deploying a Hive-based Testnet.","mainEntityOfPage":{"@type":"WebPage","@id":"setting-up-a-testnet.html"},"@type":"BlogPosting","url":"setting-up-a-testnet.html","headline":"Setting Up a Testnet","dateModified":"2020-08-26T11:52:22-07:00","datePublished":"2020-08-26T11:52:22-07:00","@context":"https://schema.org"}</script>
<!-- End Jekyll SEO tag -->


  
</head>
<body>
<header>
  <h1>
    <button type="button" class="open-nav" id="open-nav"></button>
    <a href="/"  class="logo-link"><img src="/images/logotype_black.svg" height="40" alt="Hive Developer logo"></a>
  </h1>

  
  <form action="/search/" method="get">
    <input type="text" name="q" id="search-input" placeholder="Search">
    <input type="submit" value="Search" style="display: none;">
  </form>
  

  <div id="sidebar" class="sidebar">
	
	
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/">
		<h6 class="ctrl-nav-section title">Introduction</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/#introduction-welcome">Welcome to Hive</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/quickstart/">
		<h6 class="ctrl-nav-section title">Quickstart</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/quickstart/#quickstart-choose-library">Choose Library</a></li>
						
					
						
						<li><a href="/quickstart/#quickstart-hive-full-nodes">Hive Nodes</a></li>
						
					
						
						<li><a href="/quickstart/#quickstart-testnet">Hive Testnet</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/tutorials/">
		<h6 class="ctrl-nav-section title">Tutorials</h6>
		<ul class="cont-nav-section content">
			
				
					
						<li><a href="/tutorials/#tutorials-javascript">Javascript</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-python">Python</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-ruby">Ruby</a></li>
					
				
					
						<li><a href="/tutorials/#tutorials-recipes">Recipes</a></li>
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/services/">
		<h6 class="ctrl-nav-section title">Services</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/services/#services-hive-blog">hive.blog</a></li>
						
					
						
						<li><a href="/services/#services-hivesigner">HiveSigner</a></li>
						
					
						
						<li><a href="/services/#services-jussi">Jussi</a></li>
						
					
						
						<li><a href="/services/#services-imagehoster">ImageHoster</a></li>
						
					
						
						<li><a href="/services/#services-dhf">DHF</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/apidefinitions/">
		<h6 class="ctrl-nav-section title">Appbase API</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/apidefinitions/#apidefinitions-condenser-api">Condenser Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-bridge">Bridge</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-account-by-key-api">Account By Key Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-account-history-api">Account History Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-block-api">Block Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-database-api">Database Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-debug-node-api">Debug Node Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-follow-api">Follow Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-jsonrpc">Jsonrpc</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-market-history-api">Market History Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-network-broadcast-api">Network Broadcast Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-rc-api">Rc Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-reputation-api">Reputation Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-rewards-api">Rewards Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-tags-api">Tags Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-transaction-status-api">Transaction Status Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-witness-api">Witness Api</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-broadcast-ops">Broadcast Ops</a></li>
						
					
						
						<li><a href="/apidefinitions/#apidefinitions-broadcast-ops-communities">Broadcast Ops Communities</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/resources/">
		<h6 class="ctrl-nav-section title">Resources</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/resources/#resources-overview">Overview</a></li>
						
					
						
						<li><a href="/resources/#resources-client-libs">Client Libraries</a></li>
						
					
						
						<li><a href="/resources/#resources-bluepaper">Bluepaper</a></li>
						
					
						
						<li><a href="/resources/#resources-whitepaper">Whitepaper</a></li>
						
					
						
						<li><a href="/resources/#resources-tools">Tools</a></li>
						
					
						
						<li><a href="/resources/#resources-hivesigner-libs">Hivesigner Libs</a></li>
						
					
						
						<li><a href="/resources/#resources-hive-keychain">Hive Keychain</a></li>
						
					
						
						<li><a href="/resources/#resources-developeradvocate">Community & Help</a></li>
						
					
				
			
		</ul>
	</section>
	
		
    <section class="pnl-main-nav-section main-nav-section" url="/glossary/">
		<h6 class="ctrl-nav-section title">Glossary</h6>
		<ul class="cont-nav-section content">
			
				
					
					
						
						<li><a href="/glossary/#glossary-chain-basics">Chain Basics</a></li>
						
					
						
					
						
						<li><a href="/glossary/#glossary-governance">Governance</a></li>
						
					
						
						<li><a href="/glossary/#glossary-transactions">Transactions</a></li>
						
					
						
						<li><a href="/glossary/#glossary-api">API</a></li>
						
					
						
						<li><a href="/glossary/#glossary-market">Market</a></li>
						
					
				
			
		</ul>
	</section>
	
</div>



  <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
</header>
<div class="main" id="top">
  <div class="hero">
    <h1 class="hero__h1">Hive Developer Portal </h1>
    <img class="hero__img" src="/images/honey-comb-92.png" style="position: relative; top: 10px;" />
  </div>
  <section id="tutorials-recipes-setting-up-a-testnet" class="row tutorials-recipes-setting-up-a-testnet">
	<h3>
		<a id="tutorials-recipes-setting-up-a-testnet">
			Setting Up a Testnet
			
		</a>
	</h3>
	
		<span class="description"><p>“Quick-start” for deploying a Hive-based Testnet.</p>
</span>
	

	<h3 id="intro">Intro</h3>

<p>Running a testnet is ideal for application developers who want to verify their app without broadcasting signed transactions over the mainnet.  It’s also a great way for blockchain developers to verify changes to the blockchain and can allow witnesses to get a preview of changes that they are expected to approve.</p>

<p>Setting up a testnet can be as simple as running a single Docker command, such as:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">-d</span> <span class="nt">-P</span> inertia/tintoy:latest
</code></pre></div></div>

<p>This docker command is useful for rapid testnet deploy because it only creates 2,000 accounts.</p>

<p>But in this tutorial, we will go over the <strong>no docker</strong> approach which will create all accounts that exist on mainnet.  The idea is to try to mirror the accounts and balances in proportion to the mainnet.</p>

<p>If you want full details on setting up a testnet using Tinman, head over to that github:</p>

<p>https://gitlab.syncad.com/hive/tinman</p>

<p>Otherwise, let’s do the complete Quick Start:</p>

<h3 id="sections">Sections</h3>

<ul>
  <li><a href="#minimum-requirements">Minimum Requirements</a></li>
  <li><a href="#installing-tinman">Installing Tinman</a></li>
  <li><a href="#building-hived">Building <code class="highlighter-rouge">hived</code></a></li>
  <li><a href="#snapshot">Snapshot</a></li>
  <li><a href="#configure-tinman">Configure Tinman</a></li>
  <li><a href="#actions">Actions</a></li>
  <li><a href="#configure-bootstrap-node">Configure Bootstrap Node</a></li>
  <li><a href="#bootstrap-node">Bootstrap Node</a></li>
  <li><a href="#configure-seed-node">Configure Seed Node</a></li>
  <li><a href="#seed-node">Seed Node</a></li>
  <li><a href="#gatling-optional">Gatling (Optional)</a></li>
  <li><a href="#troubleshooting">Troubleshooting</a></li>
</ul>

<h3 id="minimum-requirements">Minimum Requirements<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>This tutorial assumes Ubuntu Server 18.04 LTS 16GB RAM and 300GB SSD/HDD.</p>

<p>Running a testnet can be done on minimal hardware, but in order to build a snapshot of accounts, you should already be running your own local Hive node because getting the snapshot is time consuming and if this process is interrupted, you’ll have to start over.</p>

<p>Not only are we going to use <code class="highlighter-rouge">tinman</code> to build the snapshot, we also need to compile <code class="highlighter-rouge">hived</code> and configure it to run our testnet.</p>

<h3 id="installing-tinman">Installing Tinman<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>First, we need python (for <code class="highlighter-rouge">tinman</code>) and some other libraries:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get update
<span class="nb">sudo </span>apt-get dist-upgrade
<span class="nb">sudo </span>apt-get <span class="nb">install </span>virtualenv python3 libyajl-dev git pv
virtualenv <span class="nt">-p</span> <span class="si">$(</span>which python3<span class="si">)</span> ~/ve/tinman
<span class="nb">source</span> ~/ve/tinman/bin/activate
<span class="nb">mkdir</span> <span class="nt">-p</span> ~/src
<span class="nb">cd</span> ~/src
git clone <span class="nt">--branch</span> master https://gitlab.syncad.com/hive/tinman.git
<span class="nb">cd </span>tinman
pip <span class="nb">install </span>pipenv
pipenv <span class="nb">install
</span>pip <span class="nb">install</span> <span class="nb">.</span>
</code></pre></div></div>

<h3 id="building-hived">Building <code class="highlighter-rouge">hived</code><a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>Next, let’s build <code class="highlighter-rouge">hived</code>.  Note, we are using the <code class="highlighter-rouge">develop</code> branch but you can use whatever branch you want.  To see a list of branches that are currently being worked on, refer to: https://gitlab.syncad.com/hive/hive/-/branches/active</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>autoconf automake autotools-dev bsdmainutils <span class="se">\</span>
  build-essential cmake doxygen gdb libboost-all-dev libreadline-dev <span class="se">\</span>
  libssl-dev libtool liblz4-tool ncurses-dev pkg-config python3-dev <span class="se">\</span>
  python3-pip nginx fcgiwrap awscli gdb libgflags-dev libsnappy-dev zlib1g-dev <span class="se">\</span>
  libbz2-dev liblz4-dev libzstd-dev
<span class="nb">cd</span> ~/src
git clone <span class="nt">--branch</span> develop https://gitlab.syncad.com/hive/hive.git
<span class="nb">cd </span>hive
git submodule update <span class="nt">--init</span> <span class="nt">--recursive</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> build
<span class="nb">cd </span>build
<span class="nv">HIVE_NAME</span><span class="o">=</span>hive-tn
cmake <span class="se">\</span>
  <span class="nt">-DCMAKE_INSTALL_PREFIX</span><span class="o">=</span><span class="s2">"~/opt/</span><span class="nv">$HIVE_NAME</span><span class="s2">"</span> <span class="se">\</span>
  <span class="nt">-DCMAKE_BUILD_TYPE</span><span class="o">=</span>Release <span class="se">\</span>
  <span class="nt">-DBUILD_HIVE_TESTNET</span><span class="o">=</span>ON <span class="se">\</span>
  <span class="nt">-DLOW_MEMORY_NODE</span><span class="o">=</span>OFF <span class="se">\</span>
  <span class="nt">-DCLEAR_VOTES</span><span class="o">=</span>ON <span class="se">\</span>
  <span class="nt">-DSKIP_BY_TX_ID</span><span class="o">=</span>ON <span class="se">\</span>
  <span class="nt">-DHIVE_LINT_LEVEL</span><span class="o">=</span>OFF <span class="se">\</span>
  <span class="nt">-DENABLE_MIRA</span><span class="o">=</span>ON <span class="se">\</span>
  ..
<span class="nb">mkdir</span> <span class="nt">-p</span> ~/opt/<span class="nv">$HIVE_NAME</span>
make <span class="nt">-j</span><span class="si">$(</span><span class="nb">nproc</span><span class="si">)</span> <span class="nb">install</span>
</code></pre></div></div>

<p><strong>A note on <code class="highlighter-rouge">hived</code> branches:</strong>  Selecting a branch depends on why you’re running a testnet.  If you are doing blockchain development, you’re likely going to select your own branch where you’ve done some work that needs to be verified.  If you’re a witness, you’re likely going to select <code class="highlighter-rouge">develop</code> or <code class="highlighter-rouge">master</code> to check stability.  If you’re an application developer, you should probably select the <code class="highlighter-rouge">stable</code> branch because you want to test your app more than test the blockchain.  Application developers might also select <code class="highlighter-rouge">develop</code> to try out blockchain features that have not been released yet.</p>

<h3 id="snapshot">Snapshot<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>The snapshot is a copy of all accounts on the blockchain plus some other properties.  Having a full snapshot allows <code class="highlighter-rouge">tinman</code> to create a more realistic testnet.  Here’s how we generate a snapshot:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/src/tinman
<span class="nb">source</span> ~/ve/tinman/bin/activate
tinman snapshot <span class="nt">-s</span> http://mainnet-hive-node:8090 | pv <span class="nt">-l</span> <span class="o">&gt;</span> snapshot.json
</code></pre></div></div>

<p>In the above example, we assume that <code class="highlighter-rouge">http://mainnet-hive-node:8090</code> is our Hive node on our local network.  If you use a public node to build the <code class="highlighter-rouge">snapshot.json</code> file instead (not recommended), just remember that this process could take quite a while and can be interrupted or rate-limited.  You should consider running your own node.</p>

<p>As of August 2020, assuming the Hive mainnet node is local, this process takes approximately 20 minutes to produce a 3.6 GB output file.</p>

<h3 id="configure-tinman">Configure Tinman<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>We can take all of the defaults in <code class="highlighter-rouge">txgen.conf.example</code>, assuming you named your snapshot <code class="highlighter-rouge">snapshot.json</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/src/tinman
<span class="nb">cp </span>txgen.conf.example txgen.conf
</code></pre></div></div>

<p>We can optionally adjust <code class="highlighter-rouge">total_port_balance</code> to adjust the supply on the testnet.  But keep in mind, there is a blockchain limit defined by <code class="highlighter-rouge">HIVE_INIT_SUPPLY</code>.</p>

<h3 id="actions">Actions<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>Now that we have our <code class="highlighter-rouge">snapshot.json</code> file, we can generate the actions that will build our testnet.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/src/tinman
<span class="nb">source</span> ~/ve/tinman/bin/activate
tinman txgen <span class="nt">-c</span> txgen.conf <span class="nt">-o</span> bootstrap-init.actions
</code></pre></div></div>

<p>Building the actions is pure data-processing that doesn’t communicate with the outside world.  It only processes the JSON snapshot and config file into more JSON.  As of September 2019, this process takes approximately 90 minutes to produce a 2 GB output file.</p>

<h3 id="configure-bootstrap-node">Configure Bootstrap Node<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">HIVE_NAME</span><span class="o">=</span>hive-tn
<span class="nv">BOOTSTRAP</span><span class="o">=</span>~/data/bootstrap
<span class="nv">HIVED</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/hived
<span class="nv">$HIVED</span> <span class="nt">--data-dir</span><span class="o">=</span><span class="nv">$BOOTSTRAP</span>
</code></pre></div></div>

<p>At the startup banner, press <code class="highlighter-rouge">^C</code> (Ctrl+C) to exit <code class="highlighter-rouge">hived</code>.  As a side effect, a default data-dir is created.  Now we can purge the empty blockchain and create <code class="highlighter-rouge">config.ini</code> as follows:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-Rf</span> <span class="nv">$BOOTSTRAP</span>/blockchain
nano <span class="nv">$BOOTSTRAP</span>/config.ini
</code></pre></div></div>

<p>Then make the following changes to the generated <code class="highlighter-rouge">config.ini</code>:</p>

<ul>
  <li>Enable plugins <code class="highlighter-rouge">chain debug_node p2p webserver block_api chain_api database_api debug_node_api network_broadcast_api</code></li>
  <li>Pick a random port for p2p, say <code class="highlighter-rouge">12541</code></li>
  <li>Edit <code class="highlighter-rouge">shared-file-size</code> down, say <code class="highlighter-rouge">12G</code></li>
  <li>Pick a random port for <code class="highlighter-rouge">webserver-http-endpoint</code> and set <code class="highlighter-rouge">webserver-ws-endpoint</code> to the next-highest port.</li>
</ul>

<p>To summarize, the <em>changed</em> values are:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">plugin</span> <span class="p">=</span> <span class="s">chain debug_node p2p webserver block_api chain_api database_api debug_node_api network_broadcast_api</span>
<span class="py">shared-file-size</span> <span class="p">=</span> <span class="s">12G</span>
<span class="py">p2p-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:12541</span>
<span class="py">webserver-http-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:18751</span>
<span class="py">webserver-ws-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:18752</span>
</code></pre></div></div>

<p>Save <code class="highlighter-rouge">config.ini</code> and start <code class="highlighter-rouge">hived</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$HIVED</span> <span class="nt">--data-dir</span><span class="o">=</span><span class="nv">$BOOTSTRAP</span>
</code></pre></div></div>

<h3 id="bootstrap-node">Bootstrap Node<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>Note, the secret can be any string.  In this tutorial, we are using <code class="highlighter-rouge">hive-is-alive</code> as the secret.  Keep in mind that any person with knowledge of the secret will be able to transact using any account on your testnet.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">HIVE_NAME</span><span class="o">=</span>hive-tn
<span class="nv">GET_DEV_KEY</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/get_dev_key
<span class="nv">SIGN_TRANSACTION</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/sign_transaction

<span class="nb">cd</span> ~/src/tinman
<span class="nb">source</span> ~/ve/tinman/bin/activate

<span class="o">(</span> <span class="se">\</span>
  <span class="nb">echo</span> <span class="s1">'["set_secret", {"secret":"hive-is-alive"}]'</span> <span class="p">;</span> <span class="se">\</span>
  <span class="nb">cat </span>bootstrap-init.actions <span class="se">\</span>
<span class="o">)</span> | <span class="se">\</span>
tinman keysub <span class="nt">--get-dev-key</span> <span class="nv">$GET_DEV_KEY</span> | <span class="se">\</span>
tinman submit <span class="nt">-t</span> http://127.0.0.1:18751 <span class="se">\</span>
    <span class="nt">--signer</span> <span class="nv">$SIGN_TRANSACTION</span> <span class="se">\</span>
    <span class="nt">-f</span> die <span class="se">\</span>
    <span class="nt">--timeout</span> 600
</code></pre></div></div>

<p>The above command will send <code class="highlighter-rouge">bootstrap-init.actions</code> to the bootstrap node using “fastgen” (as rapidly as possible).  Fastgen functionality is provided by <code class="highlighter-rouge">debug_node_api</code>.  Without fastgen, this process would take 3 seconds per 40 action (by default).</p>

<h3 id="configure-seed-node">Configure Seed Node<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>Once the bootstrap is complete and we no longer need fastgen to import actions, we can start a new testnet node without <code class="highlighter-rouge">debug_node_api</code>.  For simplicity, this new seed node will also run our initial witnesses for block signing.</p>

<p>We need to keep the Bootstrap Node running, so do the following in a new shell session:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">HIVE_NAME</span><span class="o">=</span>hive-tn
<span class="nv">SEED</span><span class="o">=</span>~/data/seed
<span class="nv">HIVED</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/hived
<span class="nv">GET_DEV_KEY</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/get_dev_key
<span class="nv">$HIVED</span> <span class="nt">--data-dir</span><span class="o">=</span><span class="nv">$SEED</span>
</code></pre></div></div>

<p>Again, at the startup banner, press <code class="highlighter-rouge">^C</code> (Ctrl+C) to exit <code class="highlighter-rouge">hived</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-Rf</span> <span class="nv">$SEED</span>/blockchain
nano <span class="nv">$SEED</span>/config.ini
</code></pre></div></div>

<p>Then make the following changes to the generated <code class="highlighter-rouge">config.ini</code>:</p>

<ul>
  <li>Enable plugins <code class="highlighter-rouge">chain p2p webserver witness database_api network_broadcast_api block_api</code></li>
  <li>Pick the Bootstrap ip/port for p2p-seed-node <code class="highlighter-rouge">127.0.0.1:12541</code></li>
  <li>Pick a new port for p2p, say <code class="highlighter-rouge">2541</code></li>
  <li>Edit <code class="highlighter-rouge">shared-file-size</code> down, say <code class="highlighter-rouge">24G</code></li>
  <li>Pick a new random port for <code class="highlighter-rouge">webserver-http-endpoint</code> and set <code class="highlighter-rouge">webserver-ws-endpoint</code> to the next-highest port.</li>
  <li>Enable stale block production with <code class="highlighter-rouge">enable-stale-production = true</code></li>
  <li>Set required participation with <code class="highlighter-rouge">required-participation = 0</code></li>
  <li>Add whitelist for RC with <code class="highlighter-rouge">rc-account-whitelist = porter tnman</code></li>
  <li>TODO research: <code class="highlighter-rouge">rc-skip-reject-not-enough-rc = true</code></li>
</ul>

<p>Now we need to add the names of all of the witnesses:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>N <span class="k">in</span> <span class="si">$(</span><span class="nb">seq </span>0 21<span class="si">)</span>
<span class="k">do
</span><span class="nb">echo</span> <span class="s2">"witness = </span><span class="se">\"</span><span class="s2">init-</span><span class="nv">$N</span><span class="se">\"</span><span class="s2">"</span> <span class="o">&gt;&gt;</span> <span class="nv">$SEED</span>/config.ini
<span class="k">done</span>
</code></pre></div></div>

<p>Add their private keys as well, note we are assuming the secret is <code class="highlighter-rouge">hive-is-alive</code> for this tutorial:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>K <span class="k">in</span> <span class="si">$(</span><span class="nv">$GET_DEV_KEY</span> hive-is-alive block-init-0:21 | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s1">'"'</span> <span class="nt">-f</span> 4<span class="si">)</span>
<span class="k">do
</span><span class="nb">echo</span> <span class="s2">"private-key = </span><span class="nv">$K</span><span class="s2">"</span> <span class="o">&gt;&gt;</span> <span class="nv">$SEED</span>/config.ini
<span class="k">done</span>
</code></pre></div></div>

<p>To summarize, the <em>changed and new</em> values are:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">plugin</span> <span class="p">=</span> <span class="s">chain p2p webserver witness database_api network_broadcast_api block_api</span>
<span class="py">shared-file-size</span> <span class="p">=</span> <span class="s">24G</span>
<span class="py">p2p-seed-node</span> <span class="p">=</span> <span class="s">127.0.0.1:12541</span>
<span class="py">p2p-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:2541</span>
<span class="py">webserver-http-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:8751</span>
<span class="py">webserver-ws-endpoint</span> <span class="p">=</span> <span class="s">0.0.0.0:8752</span>
<span class="py">enable-stale-production</span> <span class="p">=</span> <span class="s">true</span>
<span class="py">required-participation</span> <span class="p">=</span> <span class="s">0</span>
<span class="py">rc-account-whitelist</span> <span class="p">=</span> <span class="s">porter tnman</span>
<span class="py">rc-skip-reject-not-enough-rc</span> <span class="p">=</span> <span class="s">true</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-0"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-1"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-2"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-3"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-4"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-5"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-6"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-7"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-8"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-9"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-10"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-11"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-12"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-13"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-14"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-15"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-16"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-17"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-18"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-19"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-20"</span>
<span class="py">witness</span> <span class="p">=</span> <span class="s">"init-21"</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5J1giwxi3QwU56N7J4WMaJiRaRmfnp5F27QPZ7itnW4o7ePuUs2</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KV3k9PJzrE6h7gvnZcrfXBjazZZ6UdCQjfePfv7hxbmWMFtZ1r</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JypUTzFq4zuyowWCjUJwsmph2Gwx49hUMVpAYT1PzbnmUDG4sh</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JqvwS7jQDY5wyCeQ9wBKAx6XgoLBf4hZZz6Cd3rb5NCP3pMiZ7</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JWQaGiV8Z9ssNCCTm5Hx2VdhEV8G82nV6RwSwAWBYQWfoM3Dzf</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KW5fY5gpTBYt7YJNBnfPWc2BzE1o6GJiLB8Hc2YaZ7sz71VFtc</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5K8aRoTDwELSyZJZLkv6mPQy2tQRQ3p2cqNVxK2tMQZfrZThg2R</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KCVYYBwkDt2TY7Eaw3TJvLRhEdxR3ruMVqyN6RPcbbCSLhDTbu</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5Jf1sxJhTo4ZEog5LDxfeA8ZFsFCivtMb2HXmx7ndw7mgq15Qqk</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5Ki39i3NL6TyxRXN7d2aJFPD2PEb4WXx1t7KrXc6KQqm5Zfame2</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5K2B9RhzdxhpuMxXCPszXgjJYqPD6PC66zmour3cfmGoLLRcNfa</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5J2sv5ELyuumaVeXpBJFE92dphvnyjmkLi2AyY28hr2iYPZ7Qh6</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JZjV98gnLGm7AxVdRbiDT5DU6pibmzUUu7bxACR87nxawj1gNC</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JFDyVEEVHAyang92s35cVH7t27GoeBg4uthWghV3yDdvj3GPcX</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KTJe4qmj7jcubLGxKQ4WB52akWkRC98sJGbNRsxjj9yN73GGTy</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KKxuTpqXWRsxzbJKdQCfK3mLJ4wqZ9eTswqtaQQ7bEaqEqGzHh</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5KV3ynnzdun28k9kJFxJZYvKUv8rPoq3bNVWajucvkCy9S9bMCv</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JBD9uVVFD6NcRo6nZnAjFKYf2RqfPRZHd8PWGJNzEnfmmcqi8K</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JiT5h3dxmiwUmfserh5yW8fjuc4zSSTkLL7t72SioqWKRJ7Sd3</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JdVzBLVucfHpfh9gupu5j4aQT5oCSuRLhcJSs2bqvNjEVMRmSt</span>
<span class="py">private-key</span> <span class="p">=</span> <span class="s">5JogZpTZurEK67skra7YkAJ7hHNBuoyScowDr82nbWoYXndeWRH</span>
</code></pre></div></div>

<p>Save <code class="highlighter-rouge">config.ini</code> and start <code class="highlighter-rouge">hived</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$HIVED</span> <span class="nt">--data-dir</span><span class="o">=</span><span class="nv">$SEED</span>
</code></pre></div></div>

<p>At this point, our Seed Node will sync blocks from the Bootstrap Node.</p>

<h3 id="seed-node">Seed Node<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>Once the Seed Node has caught up to the Bootstrap Node, it’s safe to shut down the Bootstrap Node.  The Seed Node will now take over block production.</p>

<p>Congratulations!  Your testnet is running!</p>

<h3 id="gatling-optional">Gatling (Optional)<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p>If you’d like your testnet to mirror mainnet transactions as they happen, you should run the gatling module.  Make sure your Seed Node is fully sync’d before running gatling.  Also make sure you use the same secret.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">HIVE_NAME</span><span class="o">=</span>hive-tn
<span class="nv">GET_DEV_KEY</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/get_dev_key
<span class="nv">SIGN_TRANSACTION</span><span class="o">=</span>~/opt/<span class="nv">$HIVE_NAME</span>/bin/sign_transaction

<span class="nb">cd</span> ~/src/tinman
<span class="nb">source</span> ~/ve/tinman/bin/activate

<span class="nb">cp </span>gatling.conf.example gatling.conf

<span class="o">(</span> <span class="se">\</span>
  <span class="nb">echo</span> <span class="s1">'["set_secret", {"secret":"hive-is-alive"}]'</span> <span class="p">;</span> <span class="se">\</span>
  tinman gatling <span class="nt">-c</span> gatling.conf <span class="nt">-f</span> 0 <span class="nt">-t</span> 0 <span class="nt">-o</span> - | tinman prefixsub <span class="se">\</span>
<span class="o">)</span> | <span class="se">\</span>
tinman keysub <span class="nt">--get-dev-key</span> <span class="nv">$GET_DEV_KEY</span> | <span class="se">\</span>
tinman submit <span class="nt">--realtime</span> <span class="nt">-t</span> http://127.0.0.1:8751 <span class="se">\</span>
    <span class="nt">--signer</span> <span class="nv">$SIGN_TRANSACTION</span> <span class="se">\</span>
    <span class="nt">--timeout</span> 600 <span class="se">\</span>
    <span class="nt">--fail</span> /dev/null
</code></pre></div></div>

<h3 id="troubleshooting">Troubleshooting<a style="float: right" href="#sections"><i class="fas fa-chevron-up fa-sm"></i></a></h3>

<p><strong>Problem:</strong> Got an error while trying to compile <code class="highlighter-rouge">hived</code>:</p>

<p><code class="highlighter-rouge">c++: internal compiler error: Killed (program cc1plus)</code></p>

<p>-or-</p>

<p><code class="highlighter-rouge">virtual memory exhausted: Cannot allocate memory</code></p>

<p><strong>Solution:</strong> Add more memory or enable swap.</p>

<p>To enable swap (do not enable swap on a VPS like Digital Ocean):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo dd </span><span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>/var/swap.img <span class="nv">bs</span><span class="o">=</span>1024k <span class="nv">count</span><span class="o">=</span>4000
<span class="nb">sudo chmod </span>600 /var/swap.img
<span class="nb">sudo </span>mkswap /var/swap.img
<span class="nb">sudo </span>swapon /var/swap.img
</code></pre></div></div>

<hr />

<p><strong>Problem:</strong> Got an error while trying to create <code class="highlighter-rouge">bootstrap-init.actions</code>:</p>

<p><code class="highlighter-rouge">ijson.common.IncompleteJSONError: b'parse error: premature EOF</code></p>

<p><strong>Solution:</strong> Re-run <code class="highlighter-rouge">tinman snapshot</code> in the <a href="#snapshot">Snapshot</a> section.  The snapshot was likely interrupted or you ran out of disk space while saving the snapshot.  It’s also possible you were rate-limited, if you’re using a public node, which is one of the pitfalls of using a public node.</p>

</section>

</div>
<div class="footer">
  <a href="#">Back to top</a>
</div>
<script>
    document.getElementById("open-nav").addEventListener("click", function () {
        document.body.classList.toggle("nav-open");
    });
</script>
</body>
</html>


<script src="/js/adjust.js"></script>

